#!/bin/bash
#
# This file contains the global variables and common functions
# used in the posix test scripts.
set -e

LUSTRE=${LUSTRE:-$(cd $(dirname $0)/../..; echo $PWD)}
. $LUSTRE/tests/test-framework.sh

#************************ Initialize Global Variables *************************#
export POSIX_SRC=${POSIX_SRC:-"/usr/src/posix"}
export POSIX_RUN=${POSIX_RUN:-"$POSIX_SRC/run_posix_suite.pl"}
export TEST_BIN="$POSIX_SRC/TESTROOT-gcc$(gcc -v 2>&1 | tail -1 |
		 cut -d' ' -f3)-$(uname -m).tgz"

# Root directory of the POSIX test suite installation.
export INSTALL_DIR=${INSTALL_DIR:-"$POSIX_SRC/tet"}

# Root directory from which the testsets will be executed.
export TESTEXEC_DIR=${TESTEXEC_DIR:-"$POSIX_SRC/TESTROOT"}

# Test results directory.
export RESULT_DIR=${RESULT_DIR:-"$INSTALL_DIR/test_sets/results"}

# Test groups for POSIX compliance test suite.
USER_GROUPS="vsxg0,vsxg1,vsxg2"

for i in $(seq 31); do
	SUPP_GROUPS="$SUPP_GROUPS,supp$i"
done
SUPP_GROUPS=${SUPP_GROUPS#,}

export GROUP_ID=${GROUP_ID:-"2000000000"}
export USER_ID=${USER_ID:-"2000000000"}

#***************************** Common Functions *******************************#
# Remove users and groups for running the POSIX test suite.
delete_posix_users() {
    local node=${1:-$(hostname)}

    do_nodes $node "
        for i in 0 1 2; do
            userdel vsx\\\$i;
        done;
        for group in ${SUPP_GROUPS//,/ } ${USER_GROUPS//,/ }; do
            groupdel \\\$group;
        done" 2>&1 | dshbak -c
    return ${PIPESTATUS[0]}
}

# Setup users and groups for running the POSIX test suite.
setup_posix_users() {
	local node=${1:-$HOSTNAME}
	# consistent with install.sh in LSB Test Suite
	local gid=$((GROUP_ID + 1))
	local uid=$USER_ID
	local user group
	local home
	local opts
	local i

	for group in ${USER_GROUPS//,/ } ${SUPP_GROUPS//,/ }; do
		if ! do_rpc_nodes $node add_group $gid $group; then
			delete_posix_users $node
			return 1
		fi
		gid=$((gid + 1))
	done

	for i in 0 1 2; do
		user=vsx$i
		group=vsxg$i

		if [[ "$user" = "vsx0" ]]; then
			home=$INSTALL_DIR/test_sets
			opts="-G $SUPP_GROUPS"
		else
			home=$INSTALL_DIR
			opts=""
		fi

		if ! do_rpc_nodes $node add_user $uid $user $group $home $opts
		then
			delete_posix_users $node
			return 2
		fi
		uid=$((uid + 1))
	done

	return 0
}

prep() {
    if [[ ! -d $POSIX_SRC ]]; then
        echo "Missing POSIX testsuite source"
        return 1
    fi
    [[ -f $TEST_BIN ]] && rm -f $TEST_BIN
    [[ -d $INSTALL_DIR ]] && rm -rf $INSTALL_DIR

	if egrep -q "CentOS|Red Hat|Fedora" /etc/redhat-release; then
		local prefix=/usr/lib/$(uname -m)-redhat-linux5E
		if egrep -q "Fedora" /etc/issue; then
			prefix=/usr/arm-gp2x-linux
		fi
		if grep -q "el7" <<<$(uname -r); then
			# Fix LU-9102
			prefix=/usr/local/lib/x86_64-redhat-linux5E
		fi
		[[ -d /usr/include/bits ]] || mkdir -p /usr/include/bits
		[[ -d /usr/include/sys ]] || mkdir -p /usr/include/sys
		[[ -s /usr/include/stropts.h ]] ||
			ln -s $prefix/include/stropts.h \
			/usr/include/stropts.h
		[[ -s /usr/include/bits/stropts.h ]] ||
			ln -s $prefix/include/bits/stropts.h \
			/usr/include/bits/stropts.h
		[[ -s /usr/include/bits/xtitypes.h ]] ||
			ln -s $prefix/include/bits/xtitypes.h \
			/usr/include/bits/xtitypes.h
		[[ -s /usr/include/sys/stropts.h ]] ||
			ln -s $prefix/include/sys/stropts.h \
			/usr/include/sys/stropts.h
	fi

    pushd $POSIX_SRC > /dev/null

    if [[ -f install.sh ]]; then
        [[ ! -x install.sh ]] && chmod +x install.sh
    else
        popd > /dev/null
        echo "install.sh does not exist in $POSIX_SRC."
        return 1
    fi

    popd > /dev/null
}

install() {
    pushd $POSIX_SRC > /dev/null

    log "Installing POSIX test suite"
    # Install the POSIX test suite source files
    expect -f install-posix.exp $INSTALL_DIR $TESTEXEC_DIR

    popd > /dev/null
}

build() {
    pushd $POSIX_SRC > /dev/null

    log "Building POSIX test suite"
    # Build testsets
    expect -f build-posix.exp $INSTALL_DIR $TESTEXEC_DIR $POSIX_SRC

    popd > /dev/null
}

cleanup() {
    if [[ -f $TEST_BIN ]]; then
        rm -fr $TESTEXEC_DIR
        echo "Install and build POSIX test suite successfully!"
        return 0
    else
        echo "failed to build POSIX test suite."
        return 1
    fi
}

run_posix() {
	local MNTPNT=$1
	local MGSNID=$2
	local FSNAME=$3
	local COMPARE=${4}
	local compare=""
	local rc=0
	local cmd

	[[ "x$COMPARE" != "x" ]] && compare="--compare-result"
	# command to run posix test suite
	cmd="TMP=/tmp/vsx0 TMPDIR=/tmp/vsx0 $POSIX_RUN --mountpt=$MNTPNT \
		--posix-src=$POSIX_SRC --install-dir=$INSTALL_DIR \
		--results-dir=$RESULT_DIR --nospc-dev="$MGSNID:/$FSNAME" \
		$compare 2>&1"

	# run posix test suite
	echo $cmd
	if ! eval $cmd; then
		rc=${PIPESTATUS[0]}
	fi

	return $rc
}

setup_posix() {
    log "Setting up POSIX test suite from $POSIX_SRC"
    prep || return $?
    install
    build
    cleanup
}
